using System;
using Headsight.BPMN2WF.BPMN.Schemas;
using Headsight.BPMN2WF.Testing;
using Headsight.BPMN2WF.Testing.TestObjCtors;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Headsight.BPMN2WF.Transformation.Transformers
{
    [TestClass]
    public class BPMN2WFTransformation_InclusiveGatewayTest
    {
        private BPMN2WFTranformationTester _tester;
        private BPMN2WFTransformations4TestingCtor _bpmn2WfTransMappingsCtor;

        [TestInitialize]
        public void SetUp()
        {
            _bpmn2WfTransMappingsCtor = new BPMN2WFTransformations4TestingCtor()
                .With(typeof(tInclusiveGateway), typeof(BPMN2WFTransformationInclusiveGateway))
                .WithDefault(typeof(BPMN2WFTransformation_4TestingAssign));
                
            _tester = new BPMN2WFTranformationTester().With(_bpmn2WfTransMappingsCtor).Create();
        }

        [TestMethod]
        public void Inco_2_branches_1_default_no_matches()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id3", "_name3")
                .Default()
                .ThenTask(typeof(tUserTask), "_id4", "_name4");

            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();

            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);
            const String expected = "****FourTestingActivity: _id4****";
            Assert.AreEqual(true, sw.Contains(expected));
        }

        [TestMethod]
        public void Inco_2_branches_1_default_branch1()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id3", "_name3")
                .Default()
                .ThenTask(typeof(tUserTask), "_id4", "_name4");


            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();
            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);

            const String expected1 = "****FourTestingActivity: block__id2****";
            Assert.AreEqual(true, sw.Contains(expected1));
        }

        [TestMethod]
        public void Inco_2_branches_1_default_branch2()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id3", "_name3")
                .Default()
                .ThenTask(typeof(tUserTask), "_id4", "_name4");


            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();
            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);

            const String expected1 = "****FourTestingActivity: block__id2****";
            Assert.AreEqual(true, sw.Contains(expected1));
        }

        [TestMethod]
        public void Inco_2_branches_1_default_branch1_and_branch2()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id3", "_name3")
                .Default()
                .ThenTask(typeof(tUserTask), "_id4", "_name4");


            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();
            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);

            const String expected1 = "****FourTestingActivity: block__id2****";
            const String expected2 = "****FourTestingActivity: block__id3****";
            Assert.AreEqual(true, sw.Contains(expected1));
            Assert.AreEqual(true, sw.Contains(expected2));
        }

        [TestMethod]
        public void Inco_2_branches_0_default_no_match()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id3", "_name3");

            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();

            try
            {
                _tester.Transform(tDefinitions).Execute();
                Assert.Fail("**failed**");
            }
            catch (Exception e)
            {
                const String exp = "Next flow step could not be determined and BPMN source model has not defined any default branch. BPMN execution semantics require to throw this exception.";
                Assert.AreEqual(exp, e.Message);
            }
        }

        [TestMethod]
        public void Inco_2_branches_0_default_branch1_and_branch2()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id3", "_name3");


            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();
            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);

            const String expected1 = "****FourTestingActivity: block__id2****";
            const String expected2 = "****FourTestingActivity: block__id3****";
            Assert.AreEqual(true, sw.Contains(expected1));
            Assert.AreEqual(true, sw.Contains(expected2));
        }

        [TestMethod]
        public void Inco_2_branches_0_default_branch1()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id3", "_name3");


            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();
            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);

            const String expected1 = "****FourTestingActivity: block__id2****";
            Assert.AreEqual(true, sw.Contains(expected1));
        }

        [TestMethod]
        public void Inco_2_branches_0_default_branch2()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tGwExlCtor = new tGatewayInclusiveCtor(tProCtor, "_id1").WithName("_name1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id2", "_name2")
                .IfExpression("True = True")
                .ThenTask(typeof(tUserTask), "_id3", "_name3");


            var tDefinitions = tDefCtor.With(tProCtor.With(tGwExlCtor)).Create();
            var sw = _tester.Transform(tDefinitions).Execute().ToString();

            Console.WriteLine(sw);

            const String expected1 = "****FourTestingActivity: block__id3****";
            Assert.AreEqual(true, sw.Contains(expected1));
        }
    }
}